-----------------------------
-- Simple Red Coins GUI v2 --
--    by: EeveeEuphoria    --
-----------------------------

--[[ KNOWN BUGS:
	- P-Switches cause the red coins to be collected, and causes the HUD to glitch out.

]]

--[[ Usage:
	local redCoins = require("redCoins")
	redCoins.ID = 103 -- NPC ID to track
	redCoins.NumID = 1000 -- free NPC slot for the number display to appear
	Make sure to place the red coins one after the other on the map, to ensure they have correct positioning to each other on the HUD!
	e.g. Red coin closest to the left-side of the level should be the first one you place down, then the second one, etc. until the last one is at the furthest right-side of the level.

	redCoins.x and redCoins.y changes the position of the HUD elements
	Centering it below the item drop thing can be done like this:
	redCoins.x = 345
	redCoins.y = 74

	(optional) redCoins.SFX changes the SFX used for red coins to something else.
	redCoins.SFX = "My Cool Sound.wav"
	Alternatively, you can replace "RedCoinSFX.wav" found in the redCoins folder.

	(optional) redCoins.SeqSFX sets the sound effect to play in sequence, going from 1-8, and then looping around.
	redCoins.SeqSFX = "RedCoinSound_Number_"
	redCoins.SeqFormat = ".wav"
	The full files list should read like this: "RedCoinSound_Number_1.wav", RedCoinSound_Number_2.wav" ... "RedCoinSound_Number_8.wav"
	NOTE! You need to set both SeqSFX and SeqFormat for this to have any effect! It will also ignore redCoins.SFX!

	(optional) redCoins.SeqMax sets the maximum number for the SeqSFX files, by default it's 8.
	This can be used for more pitched sounds, i.e. "RedCoinSound_Number_15.wav", assuming the file exists.
]]

--[[ todo:
	- [ ] bring everything graphics-related to onDraw
	- [ ] option for collecting 2 coins with a red coin, allowing me to be lazy and have red coins be worth 2 without any changes to coins themselves elsewhere
	- [?] play sound when it's collected
		- [ ] get sunshine's sfx
		- [ ] allow custom sound to be used
	- [ ] condense everything into a single table, like coinFX
	- [ ] use onhuddraw instead for hud drawing things ;
		- [ ] and ondraw for the numbers
	- [ ] fix problem with p-switch
		- [ ] don't run the code when p-switch is active? find a way to detect for p-switches
		- [ ] alternatively, just use a layer name, and detect if the layer is empty, ala how most levels would do the red coin star thing
]]

local redCoins = {}

redCoins.SFX = "redCoins/RedCoinSFX.wav"
redCoins.x = 234
redCoins.y = 74
redCoins.SeqMax = 8

function redCoins.onInitAPI()
    registerEvent(redCoins, "onStart")
	registerEvent(redCoins, "onTick")
	registerEvent(redCoins, "onDraw")
	registerEvent(redCoins, "onNPCKill")
end

local RedCoinActive = Graphics.loadImage(Misc.resolveFile("redCoins/redcoina.png"))
local RedCoinInactive = Graphics.loadImage(Misc.resolveFile("redCoins/redcoini.png"))
local Sparkle = Graphics.loadImage(Misc.resolveFile("graphics/effect/effect-80.png"))

local RedCoinTable = {} -- table of all coin objects at start of level
local RedCoinTable2 = {} -- table of all coin objects during gameplay
local RedCoinTableDeath = {} -- table of known Dead coins, ones that have just been collected
local RedCoinTableDeathX = {} -- positions for the coins, used for the numbers that show up
local RedCoinTableDeathY = {}
local RedCoinTableDeathNum = {}
local CountDownTimer = 14 * 8
local SparkleTimer = 6
local Sparkler = 3

function redCoins.onStart()
	if not redCoins.ID then
		error("No ID provided for redCoins!")
	end

	RedCoinTable = NPC.get(redCoins.ID, 0) -- places all the red coins into a table
	if #RedCoinTable == 0 then
		error("No NPCs found for given redCoins.ID: " .. redCoins.ID)
	end
end

function redCoins.onDraw()
	RedCoinTable2 = NPC.get(redCoins.ID, 0)

	-- [[ THE HUD ]] --
	for key, value in pairs(RedCoinTable) do
		local Drawer = RedCoinInactive
		local XOffset = 14
		if #RedCoinTable2 == 0 then
			if CountDownTimer > 0 then
				CountDownTimer = CountDownTimer - 1
			end
			XOffset = CountDownTimer / 8
		end

		if value.isValid then
			Drawer = RedCoinInactive
			if tonumber(value.x) then
				value.PrevX = value.x
				value.PrevY = value.y
			end
		else
			Drawer = RedCoinActive
			if not RedCoinTableDeath[value] then
				RedCoinTableDeath[value] = 0
				RedCoinTableDeathNum[value] = (#RedCoinTable - #RedCoinTable2)
				if not (redCoins.SeqSFX and redCoins.SeqFormat) then
					Audio.playSFX(redCoins.SFX)
				else
					local NumberTime = RedCoinTableDeathNum[value]
					if NumberTime > redCoins.SeqMax then
						NumberTime = NumberTime - (math.floor(NumberTime/redCoins.SeqMax) * redCoins.SeqMax)
					end
					Audio.playSFX(redCoins.SeqSFX .. NumberTime .. redCoins.SeqFormat)
				end
			end
		end

		if CountDownTimer > 0 then
			if key > 10 then
				local Offset1 = tonumber(string.sub(tostring(key-1), 1, 1))
				local Offset2 = tonumber(string.sub(tostring(key-1), 2, 2))
				Graphics.drawImage(Drawer,redCoins.x+(XOffset*(Offset2)),redCoins.y+(Offset1*18))
			else
				Graphics.drawImage(Drawer,redCoins.x+(XOffset*(key-1)),redCoins.y)
			end
		end
	end

	-- [ sparkles drawn when collapsing the hud ] --
	if CountDownTimer == 0 and (Sparkler > 0 and SparkleTimer > -1) then
		if SparkleTimer > 0 then
			SparkleTimer = SparkleTimer - 1
		else
			SparkleTimer = 6
			Sparkler = Sparkler - 1
		end
		SparkleYDraw = 32-(Sparkler*16)
		Graphics.drawImage(Sparkle,redCoins.x, redCoins.y, 0, SparkleYDraw, 16, 16)
	end


	-- [[ number display ]] --
	local FreezeSpot = 60
	local DisappearSpot = 85
	local SparkleTimer = 5

	for key, value in pairs(RedCoinTableDeath) do
		local Num1 = nil
		local Num2 = nil
		if RedCoinTableDeathNum[key] > 9 then
			Num1 = string.sub(tostring(RedCoinTableDeathNum[key]), 2, 2)
			Num2 = string.sub(tostring(RedCoinTableDeathNum[key]), 1, 1)
		else
			Num1 = RedCoinTableDeathNum[key]
		end

		function DrawNumber(yoffset) -- offest by 10, add 2 for space too
			if Num2 then
				Graphics.drawImageToScene(Graphics.loadImage(Misc.resolveFile("redCoins/redcoin-" .. Num2 .. ".png")), RedCoinTableDeathX[key]-10, RedCoinTableDeathY[key]+yoffset)
				Graphics.drawImageToScene(Graphics.loadImage(Misc.resolveFile("redCoins/redcoin-" .. Num1 .. ".png")), RedCoinTableDeathX[key]+5, RedCoinTableDeathY[key]+yoffset)
			else
				Graphics.drawImageToScene(Graphics.loadImage(Misc.resolveFile("redCoins/redcoin-" .. Num1 .. ".png")), RedCoinTableDeathX[key], RedCoinTableDeathY[key]+yoffset)
			end
		end

		if value < FreezeSpot then -- bouncing up, then back down
			RedCoinTableDeath[key] = value + 1
			--Text.print(tostring(key) .. " " .. tostring(value), 30, 220)
			local yoffset = -10
			yoffset = yoffset - 2*(math.sin(((value)/20)) * 70)
			DrawNumber(yoffset)
		elseif value < DisappearSpot then -- freeze in place
			RedCoinTableDeath[key] = value + 1
			local yoffset = -10
			yoffset = yoffset - 2*(math.sin(((FreezeSpot)/20)) * 70)
			DrawNumber(yoffset)
		elseif value+(SparkleTimer*3) < (value + DisappearSpot) then -- disappear into sparkles
			RedCoinTableDeath[key] = value + 1
			local TimerThing = value - DisappearSpot
			local SparkleYDraw2

			if TimerThing / SparkleTimer <= 1 then
				SparkleYDraw2 = 32
			elseif TimerThing / SparkleTimer <= 2 then
				SparkleYDraw2 = 32-(1*16)
			elseif TimerThing / SparkleTimer <= 3 then
				SparkleYDraw2 = 32-(2*16)
			else
				SparkleYDraw2 = 32-(3*16)
			end

			local yoffset = -10
			yoffset = yoffset - 2*(math.sin(((FreezeSpot)/20)) * 70)
			Graphics.drawImageToScene(Sparkle, RedCoinTableDeathX[key], RedCoinTableDeathY[key]+yoffset, 0, SparkleYDraw2, 16, 16)
		end
	end

end

function redCoins.onNPCKill(EventToken, NPC, harmType)
	if NPC.id == redCoins.ID then
		RedCoinTableDeathX[NPC] = NPC.x
		RedCoinTableDeathY[NPC] = NPC.y
	end
end

return redCoins